#include <gtest/gtest.h>
#include "utility_header.h"  // 替换为您的 Matrix 类的头文件路径

// 测试默认构造函数
TEST(MatrixTest, Constructor){
    Matrix mat;
}

TEST(MatrixTest, Dimension) {
    Matrix mat;
    mat.dimension(3, 3);
    EXPECT_EQ(mat.get_rows(), 3);
    EXPECT_EQ(mat.get_cols(), 3);
}

// 测试 Matrix 类的重载构造函数
TEST(MatrixTest, ParameterizedConstructor) {
    Matrix mat(2, 3);
    EXPECT_EQ(mat.get_rows(), 2);
    EXPECT_EQ(mat.get_cols(), 3);
}

// 测试矩阵赋值
TEST(MatrixTest, AssignLoc) {
    Matrix mat(2, 2);
    mat.assign_loc(0, 0, 1.0);
    mat.assign_loc(0, 1, 2.0);
    mat.assign_loc(1, 0, 3.0);
    mat.assign_loc(1, 1, 4.0);

    EXPECT_DOUBLE_EQ(mat.get_loc(0, 0), 1.0);
    EXPECT_DOUBLE_EQ(mat.get_loc(0, 1), 2.0);
    EXPECT_DOUBLE_EQ(mat.get_loc(1, 0), 3.0);
    EXPECT_DOUBLE_EQ(mat.get_loc(1, 1), 4.0);
}

// 测试矩阵行列式的计算
TEST(MatrixTest, Determinant) {
    Matrix mat(2, 2);
    mat.assign_loc(0, 0, 1.0);
    mat.assign_loc(0, 1, 2.0);
    mat.assign_loc(1, 0, 3.0);
    mat.assign_loc(1, 1, 4.0);

    double det = mat.determinant();
    EXPECT_DOUBLE_EQ(det, -2.0);
}

// 测试矩阵转置
TEST(MatrixTest, Transpose) {
    Matrix mat(2, 3);
    mat.assign_loc(0, 0, 1.0);
    mat.assign_loc(0, 1, 2.0);
    mat.assign_loc(0, 2, 3.0);
    mat.assign_loc(1, 0, 4.0);
    mat.assign_loc(1, 1, 5.0);
    mat.assign_loc(1, 2, 6.0);

    Matrix trans_mat = mat.trans();

    EXPECT_EQ(trans_mat.get_rows(), 3);
    EXPECT_EQ(trans_mat.get_cols(), 2);
    EXPECT_DOUBLE_EQ(trans_mat.get_loc(0, 0), 1.0);
    EXPECT_DOUBLE_EQ(trans_mat.get_loc(1, 0), 2.0);
    EXPECT_DOUBLE_EQ(trans_mat.get_loc(2, 0), 3.0);
    EXPECT_DOUBLE_EQ(trans_mat.get_loc(0, 1), 4.0);
    EXPECT_DOUBLE_EQ(trans_mat.get_loc(1, 1), 5.0);
    EXPECT_DOUBLE_EQ(trans_mat.get_loc(2, 1), 6.0);
}

TEST(MatrixTest, Identity) {
    Matrix mat(3, 3);
    mat.identity();
    EXPECT_DOUBLE_EQ(mat.get_loc(0, 0), 1.0);
    EXPECT_DOUBLE_EQ(mat.get_loc(1, 1), 1.0);
    EXPECT_DOUBLE_EQ(mat.get_loc(2, 2), 1.0);
}

TEST(MatrixTest, BuildVec3) {
    Matrix vec(3, 1);
    vec.build_vec3(1.0, 2.0, 3.0);
    EXPECT_DOUBLE_EQ(vec.get_loc(0, 0), 1.0);
    EXPECT_DOUBLE_EQ(vec.get_loc(1, 0), 2.0);
    EXPECT_DOUBLE_EQ(vec.get_loc(2, 0), 3.0);
}

TEST(MatrixTest, BuildMat33) {
    Matrix mat(3, 3);
    mat.build_mat33(1, 2, 3, 4, 5, 6, 7, 8, 9);
    EXPECT_DOUBLE_EQ(mat.get_loc(0, 0), 1);
    EXPECT_DOUBLE_EQ(mat.get_loc(1, 1), 5);
    EXPECT_DOUBLE_EQ(mat.get_loc(2, 2), 9);
}

// TEST(MatrixTest, CartFromPol) {
//     Matrix vec(3, 1);
//     vec.cart_from_pol(1, 0, M_PI/2);
//     EXPECT_NEAR(vec.get_loc(0, 0), 0, 1e-6);
//     EXPECT_NEAR(vec.get_loc(1, 0), 1, 1e-6);
//     EXPECT_NEAR(vec.get_loc(2, 0), 0, 1e-6);
// }

// TEST(MatrixTest, ColVec) {
//     Matrix mat(2, 2);
//     mat.assign_loc(0, 0, 1);
//     mat.assign_loc(0, 1, 2);
//     mat.assign_loc(1, 0, 3);
//     mat.assign_loc(1, 1, 4);
//     Matrix col = mat.col_vec(1);
//     EXPECT_DOUBLE_EQ(col.get_loc(0, 0), 2);
//     EXPECT_DOUBLE_EQ(col.get_loc(1, 0), 4);
// }

TEST(MatrixTest, DiamatVec) {
    Matrix vec(3, 1);
    vec.assign_loc(0, 0, 1);
    vec.assign_loc(1, 0, 2);
    vec.assign_loc(2, 0, 3);
    Matrix diamat = vec.diamat_vec();
    EXPECT_DOUBLE_EQ(diamat.get_loc(0, 0), 1);
    EXPECT_DOUBLE_EQ(diamat.get_loc(1, 1), 2);
    EXPECT_DOUBLE_EQ(diamat.get_loc(2, 2), 3);
}

TEST(MatrixTest, DiavecMat) {
    Matrix mat(3, 3);
    mat.assign_loc(0, 0, 1);
    mat.assign_loc(1, 1, 2);
    mat.assign_loc(2, 2, 3);
    Matrix vec = mat.diavec_mat();
    EXPECT_DOUBLE_EQ(vec.get_loc(0, 0), 1);
    EXPECT_DOUBLE_EQ(vec.get_loc(1, 0), 2);
    EXPECT_DOUBLE_EQ(vec.get_loc(2, 0), 3);
}
